package com.smart.community.region.controller;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.smart.community.feign.region.dto.OwnerInfoDTO;
import com.smart.community.region.entity.Owner;
import com.smart.community.region.entity.OwnerHousehold;
import com.smart.community.region.service.IOwnerHouseholdService;
import com.smart.community.region.service.IOwnerService;

import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.extern.slf4j.Slf4j;

/**
 * 业主Feign接口实现Controller
 * 
 * @author Wu.Liang
 * @since 2025-08-20
 * @version 1.0.0
 */
@Slf4j
@RestController
@RequestMapping("/feign/owner")
@Tag(name = "业主Feign接口", description = "业主权限相关Feign接口")
public class OwnerFeignController {

    @Autowired
    private IOwnerHouseholdService ownerHouseholdService;
    
    @Autowired
    private IOwnerService ownerService;

    /**
     * 根据业主ID获取业主信息
     * 
     * @param ownerId 业主ID
     * @return 业主信息
     */
    @GetMapping("/{ownerId}")
    @Operation(summary = "根据业主ID获取业主信息")
    public OwnerInfoDTO getOwnerById(@PathVariable("ownerId") Long ownerId) {
        log.info("根据业主ID获取业主信息，业主ID：{}", ownerId);
        try {
            Owner owner = ownerService.getById(ownerId);
            if (owner == null) {
                return new OwnerInfoDTO();
            }
            return convertToOwnerInfoDTO(owner);
        } catch (Exception e) {
            log.error("根据业主ID获取业主信息失败，业主ID：{}", ownerId, e);
            return new OwnerInfoDTO();
        }
    }
    
    /**
     * 根据用户ID获取业主信息
     * 
     * @param userId 用户ID
     * @return 业主信息
     */
    @GetMapping("/user/{userId}")
    @Operation(summary = "根据用户ID获取业主信息")
    public OwnerInfoDTO getOwnerByUserId(@PathVariable("userId") Long userId) {
        log.info("根据用户ID获取业主信息，用户ID：{}", userId);
        try {
            Owner owner = ownerService.getOwnerByUserId(userId);
            if (owner == null) {
                return new OwnerInfoDTO();
            }
            return convertToOwnerInfoDTO(owner);
        } catch (Exception e) {
            log.error("根据用户ID获取业主信息失败，用户ID：{}", userId, e);
            return new OwnerInfoDTO();
        }
    }
    
    /**
     * 根据身份证号获取业主信息
     * 
     * @param idCard 身份证号
     * @return 业主信息
     */
    @GetMapping("/id-card/{idCard}")
    @Operation(summary = "根据身份证号获取业主信息")
    public OwnerInfoDTO getOwnerByIdCard(@PathVariable("idCard") String idCard) {
        log.info("根据身份证号获取业主信息，身份证号：{}", idCard);
        try {
            Owner owner = ownerService.getOwnerByIdCard(idCard);
            if (owner == null) {
                return new OwnerInfoDTO();
            }
            return convertToOwnerInfoDTO(owner);
        } catch (Exception e) {
            log.error("根据身份证号获取业主信息失败，身份证号：{}", idCard, e);
            return new OwnerInfoDTO();
        }
    }
    
    /**
     * 根据手机号获取业主信息
     * 
     * @param phone 手机号
     * @return 业主信息
     */
    @GetMapping("/phone/{phone}")
    @Operation(summary = "根据手机号获取业主信息")
    public OwnerInfoDTO getOwnerByPhone(@PathVariable("phone") String phone) {
        log.info("根据手机号获取业主信息，手机号：{}", phone);
        try {
            Owner owner = ownerService.getOwnerByPhone(phone);
            if (owner == null) {
                return new OwnerInfoDTO();
            }
            return convertToOwnerInfoDTO(owner);
        } catch (Exception e) {
            log.error("根据手机号获取业主信息失败，手机号：{}", phone, e);
            return new OwnerInfoDTO();
        }
    }

    /**
     * 获取业主关联的房户ID列表
     * 
     * @param userId 用户ID
     * @return 房户ID列表
     */
    @GetMapping("/household-ids/{userId}")
    @Operation(summary = "获取业主关联的房户ID列表")
    public List<Long> getOwnerHouseholdIds(@PathVariable("userId") Long userId) {
        log.info("获取业主关联的房户ID列表，用户ID：{}", userId);
        try {
            // 首先根据用户ID查询业主
            Owner owner = ownerService.getOwnerByUserId(userId);
            if (owner == null) {
                log.info("用户不是业主，用户ID：{}", userId);
                return new ArrayList<>();
            }
            
            // 然后根据业主ID查询关联的房户
            List<OwnerHousehold> ownerHouseholds = ownerHouseholdService.getByOwnerId(owner.getId());
            List<Long> householdIds = ownerHouseholds.stream()
                    .map(OwnerHousehold::getHouseholdId)
                    .distinct()
                    .collect(Collectors.toList());
            
            log.info("获取业主关联的房户ID列表成功，用户ID：{}，业主ID：{}，房户数量：{}", userId, owner.getId(), householdIds.size());
            return householdIds;
        } catch (Exception e) {
            log.error("获取业主关联的房户ID列表失败，用户ID：{}", userId, e);
            return new ArrayList<>();
        }
    }
    
    /**
     * 根据业主ID获取业主关联的房户ID列表
     * 
     * @param ownerId 业主ID
     * @return 房户ID列表
     */
    @GetMapping("/household-ids-by-owner/{ownerId}")
    @Operation(summary = "根据业主ID获取业主关联的房户ID列表")
    public List<Long> getOwnerHouseholdIdsByOwnerId(@PathVariable("ownerId") Long ownerId) {
        log.info("根据业主ID获取业主关联的房户ID列表，业主ID：{}", ownerId);
        try {
            List<OwnerHousehold> ownerHouseholds = ownerHouseholdService.getByOwnerId(ownerId);
            List<Long> householdIds = ownerHouseholds.stream()
                    .map(OwnerHousehold::getHouseholdId)
                    .distinct()
                    .collect(Collectors.toList());
            
            log.info("根据业主ID获取业主关联的房户ID列表成功，业主ID：{}，房户数量：{}", ownerId, householdIds.size());
            return householdIds;
        } catch (Exception e) {
            log.error("根据业主ID获取业主关联的房户ID列表失败，业主ID：{}", ownerId, e);
            return new ArrayList<>();
        }
    }

    /**
     * 根据物业公司ID数组获取业主在物业公司可见范围内的房户ID列表
     * 
     * @param userId 用户ID
     * @param propertyCompanyIds 物业公司ID数组
     * @return 房户ID列表
     */
    @PostMapping("/household-ids-by-property-companies/{userId}")
    @Operation(summary = "根据物业公司ID数组获取业主在物业公司可见范围内的房户ID列表")
    public List<Long> getOwnerHouseholdIdsByPropertyCompanies(
            @PathVariable("userId") Long userId, 
            @RequestBody List<Long> propertyCompanyIds) {
        log.info("根据物业公司ID数组获取业主在物业公司可见范围内的房户ID列表，用户ID：{}，物业公司ID列表：{}", userId, propertyCompanyIds);
        try {
            // 这里需要实现根据物业公司ID过滤的逻辑
            // 暂时返回空列表，后续根据具体需求实现
            log.warn("根据物业公司ID过滤业主房户列表功能暂未实现，用户ID：{}", userId);
            return new ArrayList<>();
        } catch (Exception e) {
            log.error("根据物业公司ID数组获取业主在物业公司可见范围内的房户ID列表失败，用户ID：{}", userId, e);
            return new ArrayList<>();
        }
    }
    
    /**
     * 将Owner实体转换为OwnerInfoDTO
     * 
     * @param owner 业主实体
     * @return 业主信息DTO
     */
    private OwnerInfoDTO convertToOwnerInfoDTO(Owner owner) {
        if (owner == null) {
            return new OwnerInfoDTO();
        }
        
        OwnerInfoDTO dto = new OwnerInfoDTO();
        dto.setId(owner.getId());
        dto.setOwnerName(owner.getOwnerName());
        dto.setIdCard(owner.getIdCard());
        dto.setPhone(owner.getPhone());
        dto.setEmail(owner.getEmail());
        dto.setGender(owner.getGender());
        dto.setBirthDate(owner.getBirthDate());
        dto.setAddress(owner.getAddress());
        dto.setOccupation(owner.getOccupation());
        dto.setCompany(owner.getCompany());
        dto.setEmergencyContact(owner.getEmergencyContact());
        dto.setEmergencyPhone(owner.getEmergencyPhone());
        dto.setRemark(owner.getRemark());
        dto.setStatus(owner.getStatus());
        dto.setCreateTime(owner.getCreateTime() != null ? owner.getCreateTime().toString() : null);
        dto.setUpdateTime(owner.getUpdateTime() != null ? owner.getUpdateTime().toString() : null);
        
        return dto;
    }
}
